package com.xnck.ifpms.service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.nutz.dao.Cnd;
import org.nutz.dao.sql.Criteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xnck.ifpms.dao.AccountDao;
import com.xnck.ifpms.dao.ActionDao;
import com.xnck.ifpms.dao.RoleDao;
import com.xnck.ifpms.dao.UserActionDao;
import com.xnck.ifpms.dao.UserDao;
import com.xnck.ifpms.dao.UserRoleDao;
import com.xnck.ifpms.entity.Account;
import com.xnck.ifpms.entity.Action;
import com.xnck.ifpms.entity.Role;
import com.xnck.ifpms.entity.User;
import com.xnck.ifpms.entity.UserAction;
import com.xnck.ifpms.entity.UserRole;
import com.xnck.ifpms.model.TreeNode;
import com.xiaoleilu.hutool.DateUtil;
import com.xiaoleilu.hutool.StrUtil;

/**
 * 人员业务逻辑
 * @author zhangmengliang
 *
 */
@Service
public class UserService {

	@Autowired
	private UserDao userDao;
	
	@Autowired
	private RoleDao roleDao;
	
	@Autowired
	private ActionDao actionDao;
	
	@Autowired
	private UserRoleDao userRoleDao;
	
	@Autowired
	private UserActionDao userActionDao;
	
	@Autowired
	private AccountDao accountDao;
	
	/**
	 * 查询符合条件的人员数量
	 * @param userName 人员名称(为NULL时忽略，模糊匹配)
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public Integer getUsersCount(String userName){
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(userName)) {
			cri.where().andLike(User.FIELD_DISPLAYNAME, userName);
		}
		return userDao.searchCount(cri);
	}
	
	/**
	 * 分页获得人员信息
	 * @param userName 人员名称(为NULL时忽略，模糊匹配)
	 * @param currentPage 当前页
	 * @param pageSize 页大小
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public List<User> getUsers(String userName, Integer currentPage,Integer pageSize){
		if (null == currentPage || null == pageSize) {
			currentPage = 0;
			pageSize = 20;
		}
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(userName)) {
			cri.where().andLike(User.FIELD_DISPLAYNAME, userName);
		}
		cri.getOrderBy().desc(User.FIELD_ADDTIME);
		return userDao.searchByPage(cri, currentPage, pageSize);
	}
	
	/**
	 * 按主键获得人员信息
	 * @param id 主键
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public User getUser(String id){
		return userDao.get(id);
	}
	
	/**
	 * 保存人员信息，如果不存在就新增，如果存在就修改
	 * @param id 主键
	 * @param userName 人员名称
	 * @param userEnable 是否可用
	 * @param curUserId 操作者
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public User saveUser(String id, String userName, Boolean userEnable, String curUserId){
		User user = null;
		if (StrUtil.isNotBlank(id)) {
			user = userDao.get(id);
		}
		if (null == user) {
			user = this.insertUser(userName, userEnable, curUserId);
		}
		else {
			this.updateUser(user, userName, userEnable);
		}
		return user;
	}

	/**
	 * 按主键删除人员
	 * @param id
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public void delUser(String id){
		accountDao.clear(Cnd.where(Account.FIELD_USERID, "=", id));
		userDao.delete(id);
	}
	
	/**
	 * 按主键字符串批量删除人员
	 * @param ids 以","隔开的人员ID字符串
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public void delUsers(String ids){
		Criteria cri = Cnd.cri();
		cri.where().andIn(Account.FIELD_USERID, ids.split(","));
		accountDao.clear(cri);
		cri = Cnd.cri();
		cri.where().andIn(User.FIELD_ID, ids.split(","));
		userDao.clear(cri);
	}
	
	/**
	 * 新增人员
	 * @param userName 人员名称
	 * @param userEnable 可用状态
	 * @param curUserId 操作者
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	private User insertUser(String userName, Boolean userEnable, String curUserId){
		User user = new User();
		user.setId(UUID.randomUUID().toString());
		user.setDisplayname(userName);
		user.setEnable(userEnable);
		user.setAddtime(DateUtil.date());
		user.setCreaterid(curUserId);
		userDao.insert(user);
		return user;
	}
	
	/**
	 * 更新人员信息
	 * @param user 被更新的人员对象
	 * @param userName 人员名称
	 * @param userEnable 可用状态
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	private User updateUser(User user, String userName, Boolean userEnable){
		user.setDisplayname(userName);
		user.setEnable(userEnable);
		userDao.update(user);
		return user;
	}
	
	/**
	 * 获取人员关联的角色数量
	 * @param userId 人员ID
	 * @param roleName 角色名称(为NULL时忽略,模糊匹配)
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public Integer getCountRoleForUser(String userId, String roleName){
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(roleName)) {
			cri.where().andLike(Role.FIELD_DISPLAYNAME, roleName);
		}
		return roleDao.getCountRolesForUser(userId, cri);
	}
	
	/**
	 * 分页获取人员关联的角色信息集合
	 * @param userId 人员ID
	 * @param roleName 角色名称(为NULL时忽略,模糊匹配)
	 * @param currentPage 当前页
	 * @param pageSize 页大小
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public List<Role> getRoleForUser(String userId, String roleName, Integer currentPage,Integer pageSize){
		if (null == currentPage || null == pageSize) {
			currentPage = 0;
			pageSize = 20;
		}
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(roleName)) {
			cri.where().andLike(Role.FIELD_DISPLAYNAME, roleName);
		}
		cri.getOrderBy().desc(Role.FIELD_DISPLAYNAME);
		return roleDao.getRolesForUser(userId, cri, currentPage, pageSize);
	}
	
	/**
	 * 获得未与人员关联的角色数量
	 * @param userId 人员ID
	 * @param roleName 角色名称(为NULL时忽略,模糊匹配)
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public Integer getCountRoleNotForUser(String userId, String roleName){
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(roleName)) {
			cri.where().andLike(Role.FIELD_DISPLAYNAME, roleName);
		}
		return roleDao.getCountRolesNotForUser(userId, cri);
	}
	
	/**
	 * 分页获得未与人员关联的角色信息集合
	 * @param userId 人员ID
	 * @param roleName 角色名称(为NULL时忽略,模糊匹配)
	 * @param currentPage 当前页
	 * @param pageSize 页大小
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public List<Role> getRoleNotForUser(String userId, String roleName, Integer currentPage,Integer pageSize){
		if (null == currentPage || null == pageSize) {
			currentPage = 0;
			pageSize = 20;
		}
		Criteria cri = Cnd.cri();
		if (StrUtil.isNotBlank(roleName)) {
			cri.where().andLike(Role.FIELD_DISPLAYNAME, roleName);
		}
		cri.getOrderBy().desc(Role.FIELD_DISPLAYNAME);
		return roleDao.getRolesNotForUser(userId, cri, currentPage, pageSize);
	}
	
	/**
	 * 关联人员和角色
	 * @param userId 人员ID
	 * @param roleIds 以","相隔的角色ID字符串
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public void setUserRoles(String userId, String roleIds){
		if (StrUtil.isBlank(userId) || StrUtil.isBlank(roleIds)) {
			return;
		}
		Criteria cri = Cnd.cri();
		cri.where().andIn(Role.FIELD_ID, roleIds.split(","));
		List<Role> roles = roleDao.search(cri);
		User user = userDao.get(userId);
		if (null == user || roles.size() == 0) {
			return;
		}
		user.setRoles(roles);
		userDao.insertRelation(user, User.FIELD_ROLES);
	}
	
	/**
	 * 移除人员和角色的关联
	 * @param userId 人员ID
	 * @param roleIds 以","相隔的角色ID字符串
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public void removeUserRoles(String userId, String roleIds){
		if (StrUtil.isBlank(userId) || StrUtil.isBlank(roleIds)) {
			return;
		}
		Criteria cri = Cnd.cri();
		cri.where().and(UserRole.FIELD_USERID, "=", userId).andIn(UserRole.FIELD_ROLEID, roleIds.split(","));
		userRoleDao.clear(cri);
	}
	
	/**
	 * 根据父级权限获得子级权限信息，并且标识出已与传入人员关联的权限
	 * @param parentId 父级ID
	 * @param userId 人员ID
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public List<TreeNode> getActionTreeNodes(String parentId, String userId){
		List<Action> actions = actionDao.search(Cnd.where(Action.FIELD_PARENTID, "=", parentId));
		List<Action> selActions = actionDao.getActionsForUser(userId, Cnd.where(Action.FIELD_PARENTID, "=", parentId));
		List<TreeNode> treeNodes = new ArrayList<TreeNode>();
		for (Action action : actions) {
			TreeNode treeNode = new TreeNode();
			treeNode.setId(action.getId());
			if (null != action.getChildcount() && action.getChildcount() > 0) {
				treeNode.setIsParent(true);
			}
			else {
				treeNode.setIsParent(false);
			}
			treeNode.setName(action.getDisplayname());
			treeNode.setChecked(false);
			for (Action selAction : selActions) {
				if (selAction.getId().equals(action.getId())) {
					treeNode.setChecked(true);
					break;
				}
			}
			treeNodes.add(treeNode);
		}
		return treeNodes;
	}
	
	/**
	 * 关联人员和权限
	 * @param userId 人员ID
	 * @param actionIdsString 以","隔开的权限ID字符串
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public void saveSelActions(String userId, String actionIdsString){
		userActionDao.clear(Cnd.where(UserAction.FIELD_USERID, "=", userId));
		String[] actionIds = actionIdsString.split(",");
		for (String actionId : actionIds) {
			if (StrUtil.isNotBlank(actionId)) {
				UserAction userAction = new UserAction();
				userAction.setActionid(actionId);
				userAction.setUserid(userId);
				userActionDao.insert(userAction);
			}
		}
	}
	
	/**
	 * 获得人员的账号信息
	 * @param userId 人员ID
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public Account getAccount(String userId){
		List<Account> accounts = accountDao.search(Cnd.where(Account.FIELD_USERID, "=", userId));
		if (null != accounts && accounts.size() > 0) {
			return accounts.get(0);
		}
		return null;
	}
	
	/**
	 * 保存人员的账号信息，如果不存在就新建，如果存在就修改
	 * @param userId 人员ID
	 * @param loginName 登录用户名
	 * @param loginPwd 登录密码
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public void saveAccount(String userId, String loginName, String loginPwd){
		Account account = this.getAccount(userId);
		if (null != account) {
			account.setAccount(loginName);
			account.setPassword(loginPwd);
			accountDao.update(account);
		}
		else {
			account = new Account();
			account.setId(UUID.randomUUID().toString());
			account.setAccount(loginName);
			account.setPassword(loginPwd);
			account.setUserid(userId);
			accountDao.insert(account);
		}
	}
}
